package org.pet.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.pet.entity.User;
import org.pet.entity.UserVo;
import org.pet.entity.wxlogin.LoginRequest;
import org.pet.entity.wxlogin.WxSessionResponse;
import org.pet.mapper.UserMapper;
import org.pet.service.UserService;
import org.pet.util.JWTUtils;
import org.pet.util.MD5Utils;
import org.pet.util.Result;
import org.pet.util.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service
public class UserServiceImpl implements UserService {

    private static final Integer ID = 1;
    private static final String NAME = "系统管理员";

    @Value("${wx.appid}")
    private String appId;

    @Value("${wx.appSecret}")
    private String secret;

    @Value("${wx.password}")
    private String password;

    private static final String WX_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";

    @Autowired
    private UserMapper userMapper;

//wx
    @Override
    public Result wxLogin(LoginRequest loginRequest) {
        String code = loginRequest.getCode();
        //组装微信接口
        String url = String.format("%s?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                WX_LOGIN_URL, appId, secret, code);

        RestTemplate restTemplate = new RestTemplate();
        String response = restTemplate.getForObject(url, String.class);
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            //将string转换为WxSessionResponse对象，方便获取openid
            WxSessionResponse wxSessionResponse = objectMapper.readValue(response, WxSessionResponse.class);
            if (wxSessionResponse == null || wxSessionResponse.getOpenid() == null) {
                return Result.error("登录失败");
            }
            String openid = wxSessionResponse.getOpenid();
            //判断用户是否存在
            User user = getUserByOpenid(openid);
            if(user == null){
                //如果用户不存在，注册这个用户
                User newUser = new User();
                //处理用户信息
                newUser.setName(openid);
                newUser.setNickName(loginRequest.getNickName());
                newUser.setOpenid(openid);
                if(loginRequest.getPic() != null){
                    newUser.setPic(loginRequest.getPic());//若授权了头像
                }
                newUser.setPassword(MD5Utils.MD5(password));//加密密码，微信用户第一次创建密码为默认密码
                newUser.setCreateTime(LocalDateTime.now());//将当前时间设为创建时间
                newUser.setModifyTime(LocalDateTime.now());//将当前时间设为修改时间
                newUser.setRemove(0);//未删除状态
                userMapper.wxInsert(newUser);
                User loginUser = getUserByOpenid(openid);
                //根据注册用户生成token
                return  Result.success(getToken(loginUser.getId(), loginUser.getName()));
            }
            return Result.success(getToken(user.getId(), user.getName()));
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public User getUserByOpenid(String openid) {
        return userMapper.getUserByOpenid(openid);
    }

//pc
    //根据用户名获取用户
    @Override
    public User getUserByUsername(String name) {
        return userMapper.getUserByUsername(name);
    }

    //根据id查找用户
    @Override
    public UserVo getUserById(Integer id) {


        UserVo userVo = userMapper.getUserById(id);

        return userVo;
    }

    //登录
    @Override
    public Result login(String name, String password) {
        //根据用户名获取用户
        User loginuser = userMapper.getUserByUsername(name);
        //判断用户是否存在
        if (loginuser == null) {
            return Result.error("用户不存在");
        }
        //比对密码是否正确
        if (MD5Utils.MD5(password).equals(loginuser.getPassword())) {
            return Result.success(getToken(loginuser.getId(), name));
        } else return Result.error("密码错误");
    }

    //根据id和用户名生成token
    private String getToken(Integer id, String name){
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", id);
        claims.put("name", name);
        return JWTUtils.getToken(claims);
    }

    //注册
    @Override
    public Result add(User user) {
        User exituser = userMapper.getUserByUsername(user.getName());
        if (exituser == null) {//用户不存在，可以创建

            //处理用户信息
            user.setPassword(MD5Utils.MD5(user.getPassword()));//加密密码
            user.setCreateTime(LocalDateTime.now());//将当前时间设为创建时间
            user.setModifyTime(LocalDateTime.now());//将当前时间设为修改时间
            user.setRemove(0);//未删除状态
            return userMapper.insert(user) == 0 ? Result.error("操作失败") : Result.success();
        } else {
            return Result.error("用户名已存在");
        }

    }

    //更新基本信息
    @Override
    public Result update(User user) {
        Map<String,Object> claims = ThreadLocalUtil.get();
        Integer id = (Integer) claims.get("id");
        if (!Objects.equals(id, user.getId())) {
            return Result.error("没有权限");
        }
        return userMapper.update(user) == 0 ? Result.error("操作失败") : Result.success();
    }

    //更新密码
    @Override
    public Result updatePwd(Integer id, String oldPwd, String newPwd) {
        User loginuser = userMapper.getUser(id);
        String password = MD5Utils.MD5(newPwd);
        if (NAME.equals(loginuser.getName())) {//系统管理员可以直接修改密码
            return userMapper.updatePwd(id, password) == 0 ? Result.error("操作失败") : Result.success();
        }
        //判断oldPwd是否正确
        if (!loginuser.getPassword().equals(MD5Utils.MD5(oldPwd))) {
            return Result.error("密码错误");
        }
        //对新密码加密
        return userMapper.updatePwd(id, password) == 0 ? Result.error("操作失败") : Result.success();
    }

    //伪删除
    @Override
    public Result delete(Integer id) {
        Map<String,Object> claims = ThreadLocalUtil.get();
        Integer loginId = (Integer) claims.get("id");
        if (Objects.equals(id,ID)) {//系统管理员可以直接删除
            return userMapper.delete(id) == 0 ? Result.error("操作失败") : Result.success();
        }
        if (!Objects.equals(id,loginId)) {//判断是否是当前用户自己删除
            return Result.error("无权限");
        }
        return userMapper.delete(id) == 0 ? Result.error("操作失败") : Result.success();
    }

}
